package com.ddw.meedeeuh.tests;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class AsyncResult<R> {

	private CountDownLatch latch = new CountDownLatch(1);
	private boolean hasBeenSet = false;
	private R result = null;
	private Throwable exception = null;

	public void await(int milliseconds) throws InterruptedException {
		this.latch.await(milliseconds, TimeUnit.MILLISECONDS);
	}

	public synchronized void setResult(R result) {
		if(this.hasBeenSet) {
			throw new RuntimeException("Result or Exception already set, invalid state");
		}

		this.hasBeenSet = true;
		this.result = result;
		this.latch.countDown();
	}

	public synchronized void setException(Throwable e) {
		if(this.hasBeenSet) {
			throw new RuntimeException("Result or Exception already set, invalid state");
		}

		this.hasBeenSet = true;
		this.exception = e;
		this.latch.countDown();
	}

	public synchronized boolean hasBeenSet() {
		return this.hasBeenSet;
	}

	public synchronized R getResult() {
		return this.result;
	}

	public synchronized Throwable getException() {
		return this.exception;
	}

	public synchronized void reset() {
		this.exception = null;
		this.hasBeenSet = false;
		this.result = null;
		this.latch = new CountDownLatch(1);
	}

}